"""
聊天室

使用面向对象封装，加载ui/Ui_chat_widget.py
"""
import socket

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import sys
sys.path.append("..")

from drivers.driver_chat_room import *
from models.chat_models import ChatRoom
from ui.Ui_chat_dialog import Ui_ChatDialog

class ChatDialog(QDialog):

    def __init__(self, parent=None, server_ip = "", server_port = 0, nickname: str = "匿名"):
        super().__init__(parent)
        # 创建对象
        self.ui = Ui_ChatDialog()
        self.ui.setupUi(self)

        self.setWindowTitle("聊天室")
        
        self.room:ChatRoom = ChatRoom(server_ip, server_port)

        # 初始化聊天室
        self.chat_room_client = ChatRoomClient(nickname, self.on_msg_recv)
        self.chat_room_client.enter(self.room)

        self.ui.edit_notify.appendPlainText("<畅所欲言>")
        self.ui.edit_notify.appendPlainText(
            "聊天室地址：\n{}:{}".format(self.room.ip, self.room.port)
        )

        # 创建 Ctrl+Enter 快捷键
        shortcut = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Return), self)
        shortcut.activated.connect(self.handle_shortcut)

        self.msg_string_list = []
        self.members_model = QStringListModel()
        # 初始化内容
        self.init_ui()
        self.init_data()

    def handle_shortcut(self):
        # 处理 Ctrl+Enter 快捷键的逻辑
        self.ui.btn_send.click()

    def on_msg_recv(self, msg_type: int, msg):
        if msg_type == CODE_MSG_HISTORY:
            self.init_msgs(msg)
        elif msg_type == CODE_NEW_MSG:
            self.append_msg(msg[0])
        elif msg_type == CODE_NOTICE:
            self.ui.edit_notify.clear()
            self.ui.edit_notify.setPlainText(msg["notice"])
            name = msg["name"]
            ip = msg["ip"]
            port = msg["port"]
            self.setWindowTitle(f"聊天室 [{name}] ({ip}:{port})")
        elif msg_type == CODE_CLIENT_LIST:
            # print(msg
            """
            [
                ['bbb', ['192.168.31.222', 50509]],
                ['ccc', ['192.168.31.223', 12345]]
            ]
            """
            client_list = [f"{item[0]} ({item[1][0]})" for item in msg]
            self.members_model.setStringList(client_list)
            
        if msg_type == 100:
            QMessageBox.warning(self, "警告", msg)
            self.close()

    def on_close_click(self):
        # 关闭
        self.close()

    def on_send_click(self):
        text = self.ui.edit_input.toPlainText()
        self.ui.edit_input.clear()

        text = text.strip()
        if not text:
            return

        self.chat_room_client.send(text)

        # msg = {
        #     "nickname": "张三",
        #     "from": "192.168.23.132",
        #     "time": "2023-6-11 23:30:34",
        #     "message": text
        # }
        # self.append_msg(msg)

    def init_msgs(self, msgs):
        self.msg_string_list = msgs
        for msg in self.msg_string_list:
            self.append_msg_to_widget(msg)
        # 自动将最后一行滚动到屏幕最下方
        self.ui.edit_msg_list.moveCursor(QTextCursor.End)

    def append_msg(self, msg):
        self.msg_string_list.append(msg)
        self.append_msg_to_widget(msg)
        # 自动将最后一行滚动到屏幕最下方
        self.ui.edit_msg_list.moveCursor(QTextCursor.End)

    def append_msg_to_widget(self, msg):
        # 如果不符合规则，则直接返回
        if not isinstance(msg, dict):
            return

        # 如果没有nickname、from、time、message，则直接返回
        required_field = ["nickname", "from", "time", "message"]
        if not all([key in msg for key in required_field]):
            return

        # 添加用户信息到edit_msg_list (使用html格式，颜色为蓝色)
        self.ui.edit_msg_list.appendHtml(
            f'<font color="blue">{msg["nickname"]}</font>'
            f'<font color="gray">({msg["from"]})</font> '
            f'<font color="blue">{msg["time"]}: </font>'
        )
        # 添加黑色消息内容到edit_msg_list
        self.ui.edit_msg_list.appendHtml("<font color='black'>{}</font>".format(msg["message"]))
        # 添加空行
        self.ui.edit_msg_list.appendPlainText("")

    def init_ui(self):
        # self.edit_msg_list
        self.ui.btn_close.clicked.connect(self.on_close_click)
        self.ui.btn_send.clicked.connect(self.on_send_click)

    def init_data(self):
        # 填充一些假的用户信息到list_members
        self.members_model.setStringList([
            "张三(192.168.23.2)",
            "李四(192.168.23.3)",
            "王五(192.168.23.4)",
            "赵六(192.168.23.5)",
        ])
        self.ui.list_members.setModel(self.members_model)

    # Dialog关闭时，执行self.chat_room_client.exit()
    def closeEvent(self, event):
        if self.chat_room_client is not None:
            self.chat_room_client.exit()
        event.accept()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ip = "192.168.23.222"
    room = {
        "name": "00后天团",
        "ip": ip,
        "port": 8001
    }
    widget = ChatDialog(None, ip, 8001, "小小黑球")
    widget.show()

    sys.exit(app.exec_())
